﻿using System.Linq;
using CID.Domain.Audit;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;
using Rhino.Mocks;

namespace CID.Domain.Tests.Audit
{
    [TestFixture]
    public class VersionDeploymentLogTests : BaseFunctionalTests
    {
        private const string Parameter1Name = "FirstParameter";
        private const string Parameter2Name = "SecondParameter";
        private const string Parameter3Name = "ThirdParameter";
        private const string Parameter4Name = "FourthParameter";
        private const string Parameter5Name = "FifthParameter";
        private const string Parameter6Name = "SixthParameter";
        private const string Parameter7Name = "SenventhParameter";

        [Test]
        public void CreateVersionDeploymentLog()
        {
            var environment = Operations.StubsBuilder.BuildEnvironmentStub();
            var parameter1 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.String, Parameter1Name, Infrastructure.StubsBuilder.BuildDeploymentTemplateStub());
            var parameter2 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.Integer, Parameter2Name, Infrastructure.StubsBuilder.BuildDeploymentTemplateStub());
            var parameter3 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.Decimal, Parameter3Name, Infrastructure.StubsBuilder.BuildDeploymentTemplateStub());
            var parameter4 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.DateTime, Parameter4Name, Infrastructure.StubsBuilder.BuildActivationTemplateStub());
            var parameter5 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.Boolean, Parameter5Name, Infrastructure.StubsBuilder.BuildActivationTemplateStub());
            var parameter6 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.UniqueIdentifier, Parameter6Name, Infrastructure.StubsBuilder.BuildDeactivationTemplateStub());
            var parameter7 = Infrastructure.StubsBuilder.BuildParameterStub(ParameterType.Xml, Parameter7Name, Infrastructure.StubsBuilder.BuildDeactivationTemplateStub());
            var parameterValue1 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter1);
            var parameterValue2 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter2);
            var parameterValue3 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter3);
            var parameterValue4 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter4);
            var parameterValue5 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter5);
            var parameterValue6 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter6);
            var parameterValue7 = Infrastructure.StubsBuilder.BuildEnvironmentParameterValueStub(environment, parameter7);
            var deploymentTemplate = Infrastructure.StubsBuilder.BuildDeploymentTemplateStub();
            var deploymentDefinition = Infrastructure.StubsBuilder.BuildDeploymentDefinitionStub(deploymentTemplate);
            deploymentDefinition.Stub(x => x.GetDeploymentParamaterValues(environment)).Return(new IParameterValue[] { parameterValue1, parameterValue2, parameterValue3 });
            var component = Development.StubsBuilder.BuildComponentStub(activationDeactivationDefinition: Infrastructure.StubsBuilder.BuildActivationDeactivationDefinition());
            component.ActivationDeactivationDefinition.Stub(x => x.GetActivationParamaterValues(environment)).Return(new IParameterValue[] { parameterValue4, parameterValue5 });
            component.ActivationDeactivationDefinition.Stub(x => x.GetDeactivationParamaterValues(environment)).Return(new IParameterValue[] { parameterValue6, parameterValue7 });
            var version = Development.StubsBuilder.BuildVersionStub(component);
            version.Stub(x => x.DeploymentDefinition).Return(deploymentDefinition);
            var releaseDeploymentLog = StubsBuilder.BuildReleaseDeploymentLogStub(environment);

            var versionDeploymentLog = new VersionDeploymentLog(releaseDeploymentLog, version);

            Assert.AreEqual(releaseDeploymentLog, versionDeploymentLog.ReleaseDeploymentLog);
            Assert.AreEqual(version, versionDeploymentLog.Version);
            Assert.AreEqual(deploymentTemplate, versionDeploymentLog.DeploymentTemplate);
            Assert.AreEqual(3, versionDeploymentLog.DeploymentParameters.Count());
            CollectionAssert.AllItemsAreInstancesOfType(versionDeploymentLog.ActivationParameters, typeof(ActivationParameterDeploymentLog));
            CollectionAssert.AllItemsAreInstancesOfType(versionDeploymentLog.DeactivationParameters, typeof(DeactivationParameterDeploymentLog));
            CollectionAssert.AllItemsAreInstancesOfType(versionDeploymentLog.DeploymentParameters, typeof(DeploymentParameterDeploymentLog));
            CollectionAssert.AreEquivalent(new string[] { Parameter1Name, Parameter2Name, Parameter3Name }, versionDeploymentLog.DeploymentParameters.Select(x => x.ParameterName));
            CollectionAssert.AreEquivalent(new string[] { Parameter4Name, Parameter5Name }, versionDeploymentLog.ActivationParameters.Select(x => x.ParameterName));
            CollectionAssert.AreEquivalent(new string[] { Parameter6Name, Parameter7Name }, versionDeploymentLog.DeactivationParameters.Select(x => x.ParameterName));
            CollectionAssert.AreEquivalent(new string[] { Parameter1Name, Parameter2Name, Parameter3Name, Parameter4Name, Parameter5Name, Parameter6Name, Parameter7Name}, versionDeploymentLog.Parameters.Select(x => x.ParameterName));
        }
    }
}
